/*******************************************************************************
*  file    : main.cpp
*  created : 29.07.2013
*  author  :
*******************************************************************************/

#include <memory>
#include <QDebug>
#include <QTimer>
#include <QDir>

#include <qlogger.hpp>
#include <utils.hpp>

#include "application.hpp"
#include "ctrlchandler.hpp"
#include "modemmanager.hpp"
#include "archivedb.hpp"
#include "rpcserver.hpp"
#include "messagehandler.hpp"
#include "version.hpp"

namespace
{
QLogger* l = QLoggerEngine::getLogger("core");
}

int main(int argc, char *argv[])
{
    int app_res = 0;
    try
        {
            QDir dir(QStringLiteral("../libqt/plugins"));
            QStringList dirs;
            dirs << QCoreApplication::libraryPaths();
            dirs << dir.absolutePath();
            dir.setPath(QStringLiteral("../libq5/plugins"));
            dirs << dir.absolutePath();
            QCoreApplication::setLibraryPaths(dirs);

            QCoreApplication::setApplicationName   (QLatin1String("Sleeper"              ));
            QCoreApplication::setOrganizationName  (QLatin1String("Slyshyk 0."           ));
            QCoreApplication::setOrganizationDomain(QLatin1String("alexSlyshyk@gmail.com"));

            Application a(argc, argv);
            installCtrlCHandler();

            QLoggerConsoleAppender* con_apdr =
                new QLoggerConsoleAppender(LevelError|LevelFatal|LevelCritical|LevelException
                                           ,stdout,"%d\t<%l>\t{%c}\t%m[%f:%i]%n", "hh:mm:ss");
            QLoggerRollingFileAppender* rol_apdr =
                new QLoggerRollingFileAppender(LevelError|LevelFatal|LevelCritical|LevelException,
                                               QString("%1/%2").arg(a.logDir()).arg("modemsrv.log"),
                                               "%d\t<%l>\t{%c}\t%m[%f:%i]%n",
                                               1024*1024*5);

            l->addAppender(con_apdr);
            l->addAppender(rol_apdr);

            con_apdr =
                new QLoggerConsoleAppender( LevelInfo
                                            ,stdout,"%d\t<%l>\t{%c}\t%m%n", "hh:mm:ss");
            rol_apdr =
                new QLoggerRollingFileAppender( LevelInfo,
                                                QString("%1/%2").arg(a.logDir()).arg("modemsrv.log"),
                                                "%d\t<%l>\t{%c}\t%m%n",
                                                1024*1024*5);
            l->addAppender(con_apdr);
            l->addAppender(rol_apdr);

            OptionParser parser(a.arguments(),
                                QString("usage: {program} [options] \n"
                                        "\nA program for control gsm modem.\n"),
                                QString("\nVersion %1 Copyright (c) 2013 Slyshyk Oleksiy. ")
                                .arg(Version::versionString())
                                );
            parser.addStringOption ("s", "serial" )->setDefaultValue("OPT_INVALID");
            parser.addIntegerOption("b", "baud"   )->setDefaultValue(115200);
            parser.addIntegerOption("p", "port"   )->setDefaultValue(8080);
            parser.addStringOption ("i", "address")->setDefaultValue("127.0.0.1");
            parser.addBooleanOption("v", "verbose")->setDefaultValue(false);
            parser.addStringOption ("d", "data"   )->setDefaultValue("OPT_INVALID");
            if(a.arguments().size() == 1)
                {
                    parser.usage();
                    return 1;
                }

            if( !parser.parse())
                {
                    if(parser.helpPrinted())
                        {
                            return 0;
                        }

                    logError(l,QString(QObject::tr("Ошибка разбора опций командной строки. %1"))
                             .arg(a.arguments().join(" ")));
                    return 1;
                }

            if(parser.boolean("verbose"))
                {
                    con_apdr =
                        new QLoggerConsoleAppender( LevelDebug | LevelWarn
                                                    ,stdout,"%d\t<%l>\t{%c}\t%m%n", "hh:mm:ss");
                    rol_apdr =
                        new QLoggerRollingFileAppender( LevelDebug | LevelWarn,
                                                        QString("%1/%2").arg(a.logDir()).arg("modemsrv.log"),
                                                        "%d\t<%l>\t{%c}\t%m%n",
                                                        1024*1024*5);
                    l->addAppender(con_apdr);
                    l->addAppender(rol_apdr);
                }

            qDebug()<<"Modem Manager ver."<<Version::versionString()
                    <<". Rev."            <<Version::globalRevision()
                    <<". Build"           <<Version::buildDate()<<" at "<<Version::buildTime();

            installMyMessageHandler();

            std::unique_ptr<RpcServer> rs = std::unique_ptr<RpcServer>( new RpcServer );
            rs->setAddress(parser.string ("address"));
            rs->setPort   (parser.integer("port"   ));
            QTimer::singleShot(100, rs.get(), SLOT(start()) );

            ModemManager::instance()->setModemPort(parser.string("serial"));
            ModemManager::instance()->setModemBaudrate(parser.integer("baud"));
            QTimer::singleShot(50, ModemManager::instance(), SLOT(start()) );

            if(parser.string("data") != "OPT_INVALID")
                ArchiveDB::instance()->setDatabaseName(parser.string("data"));
            QTimer::singleShot(0, ArchiveDB::instance(), SLOT(start()) );

            app_res = a.exec();
        }
    catch(...)
        {
            app_res = 0xDEADBEAF;
        }
    return app_res;
}
